﻿using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using WPF.Common;

namespace TB4
{
    [TemplatePart( Name = "PART_RootSelector", Type = typeof(Selector))]
    public class GroupToolbar : ToolBar
    {
        private List<Selector> _groups;
        private Selector _rootSelector;

        static GroupToolbar()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof (GroupToolbar), new FrameworkPropertyMetadata(typeof (GroupToolbar)));
        }

        public GroupToolbar()
        {
            Loaded += OnLoaded;
            
            
        }

        public Selector RootSelector
        {
            get { return _rootSelector; }
            set { _rootSelector = value; }
        }

        public List<Selector> Groups
        {
            get { return _groups; }
            set
            {
                _groups = value;
                foreach (Selector selector in value)
                {
                    selector.IsKeyboardFocusWithinChanged += SelectorOnIsKeyboardFocusWithinChanged;
                }
            }
        }

        private void OnSelectionChanged(object sender, SelectionChangedEventArgs selectionChangedEventArgs)
        {
            if (selectionChangedEventArgs.OriginalSource == _rootSelector)
            {
                if (Groups == null)
                    return;

                // Busca el elemento seleccionado en los selectores de segundo nivel
                foreach (Selector group in Groups)
                {
                    if (group.Items.Contains(_rootSelector.SelectedItem))
                    {
                        SelectedGroup = group;
                        break;
                    }
                }
            }
        }

        private void SelectorOnIsKeyboardFocusWithinChanged(object sender, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            if ((bool) dependencyPropertyChangedEventArgs.NewValue)
            {
                SelectedGroup = (Selector) sender;
            }
        }

        private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
        {
            Groups = _rootSelector.GetDescendants<Selector>();
            _rootSelector.SelectionChanged += OnSelectionChanged;
        }


        public override void OnApplyTemplate()
        {
            RootSelector = GetTemplateChild("PART_RootSelector") as Selector;
            base.OnApplyTemplate();
        }

        #region SelectedGroup

        public static readonly DependencyProperty SelectedGroupProperty =
            DependencyProperty.Register("SelectedGroup", typeof (Selector), typeof (GroupToolbar),
                                        new FrameworkPropertyMetadata(null,
                                                                      OnSelectedGroupChanged));


        public Selector SelectedGroup
        {
            get { return (Selector) GetValue(SelectedGroupProperty); }
            set { SetValue(SelectedGroupProperty, value); }
        }


        private static void OnSelectedGroupChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var target = (GroupToolbar) d;
            var oldSelectedGroup = (Selector) e.OldValue;
            Selector newSelectedGroup = target.SelectedGroup;
            target.OnSelectedGroupChanged(oldSelectedGroup, newSelectedGroup);
        }


        protected virtual void OnSelectedGroupChanged(Selector oldSelectedGroup, Selector newSelectedGroup)
        {
            //if (oldSelectedGroup!=null)
            //    BindingOperations.ClearAllBindings(oldSelectedGroup);

            var b = new Binding("SelectedItem") {Source = this, Mode = BindingMode.TwoWay};

            newSelectedGroup.SetBinding(Selector.SelectedItemProperty, b);

            SelectedItem = newSelectedGroup.SelectedItem;
        }

        #endregion

        #region ToolbarItemTemplate

        /// <summary>
        /// ToolbarItemTemplate Dependency Property
        /// </summary>
        public static readonly DependencyProperty ToolbarItemTemplateProperty =
            DependencyProperty.Register("ToolbarItemTemplate", typeof(DataTemplate), typeof(GroupToolbar),
                new FrameworkPropertyMetadata((DataTemplate)null));

        /// <summary>
        /// Gets or sets the ToolbarItemTemplate property. This dependency property 
        /// indicates ....
        /// </summary>
        public DataTemplate ToolbarItemTemplate
        {
            get { return (DataTemplate)GetValue(ToolbarItemTemplateProperty); }
            set { SetValue(ToolbarItemTemplateProperty, value); }
        }

        #endregion

        #region SelectorContextMenuItemTemplate

        /// <summary>
        /// SelectorContextMenuItemTemplate Dependency Property
        /// </summary>
        public static readonly DependencyProperty SelectorContextMenuItemTemplateProperty =
            DependencyProperty.Register("SelectorContextMenuItemTemplate", typeof(DataTemplate), typeof(GroupToolbar),
                new FrameworkPropertyMetadata((DataTemplate)null));

        /// <summary>
        /// Gets or sets the SelectorContextMenuItemTemplate property. This dependency property 
        /// indicates ....
        /// </summary>
        public DataTemplate SelectorContextMenuItemTemplate
        {
            get { return (DataTemplate)GetValue(SelectorContextMenuItemTemplateProperty); }
            set { SetValue(SelectorContextMenuItemTemplateProperty, value); }
        }

        #endregion

        #region SelectorContextMenuItemContainerStyle

        /// <summary>
        /// SelectorContextMenuItemContainerStyle Dependency Property
        /// </summary>
        public static readonly DependencyProperty SelectorContextMenuItemContainerStyleProperty =
            DependencyProperty.Register("SelectorContextMenuItemContainerStyle", typeof(Style), typeof(GroupToolbar),
                new FrameworkPropertyMetadata((Style)null));

        /// <summary>
        /// Gets or sets the SelectorContextMenuItemContainerStyle property. This dependency property 
        /// indicates ....
        /// </summary>
        public Style SelectorContextMenuItemContainerStyle
        {
            get { return (Style)GetValue(SelectorContextMenuItemContainerStyleProperty); }
            set { SetValue(SelectorContextMenuItemContainerStyleProperty, value); }
        }

        #endregion

        #region SelectedItem

        /// <summary>
        /// SelectedItem Dependency Property
        /// </summary>
        public static readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register("SelectedItem", typeof(object), typeof(GroupToolbar),
                new FrameworkPropertyMetadata((object)null,
                    new PropertyChangedCallback(OnSelectedItemChanged)));

        /// <summary>
        /// Gets or sets the SelectedItem property. This dependency property 
        /// indicates ....
        /// </summary>
        public object SelectedItem
        {
            get { return (object)GetValue(SelectedItemProperty); }
            set { SetValue(SelectedItemProperty, value); }
        }

        /// <summary>
        /// Handles changes to the SelectedItem property.
        /// </summary>
        private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            GroupToolbar target = (GroupToolbar)d;
            object oldSelectedItem = (object)e.OldValue;
            object newSelectedItem = target.SelectedItem;
            target.OnSelectedItemChanged(oldSelectedItem, newSelectedItem);
        }

        /// <summary>
        /// Provides derived classes an opportunity to handle changes to the SelectedItem property.
        /// </summary>
        protected virtual void OnSelectedItemChanged(object oldSelectedItem, object newSelectedItem)
        {
            _rootSelector.SelectedItem = newSelectedItem;
        }

        #endregion


    }
}